
#include "lib_jpeg.h"

#define  MAX_IMAGE_W      	  (8192)
#define  MAX_IMAGE_H     	  (8192)
#define  MAX_IMAGE_BPP        (3)



#define CODEC_ALIGN(x, a)   (((x)+(a)-1)&~((a)-1))


static  char * image_src_buff  = NULL;
static  char * image_dst_buff  = NULL;

static  char * image_dst_rotate_buff  = NULL;

int show_jpeg5(const char *data_buff,int w ,int h)
{

	int i,j;
	int a = 0;
	int r = 0;
	int g = 0;
	int b = 0;

	int temp = 0;

	int width  = w;
	int height = h;

	int x_start = 0;
	int y_start = 0;

	long start_time = 0;
	long end_time   = 0;
	
	uint32_t word;
	//*****************************************************

	if(!data_buff)
		return 0;
	//*****************************************************

	x_start = (LCD_WIDTH  - width)/2;
	y_start = (LCD_HEIGHT - height)/2;

#if 0
	log_i("x_start=%d\n",x_start);
	log_i("y_start=%d\n",y_start);

	log_i("width =%d\n",width);
	log_i("height=%d\n",height);
#endif
	//*****************************************************

	start_time = platform_get_microsecond();

	for(i=0;i<LCD_HEIGHT;i++)
	{
		for(j=0;j<LCD_WIDTH;j++)
		{
			if((i >= y_start)&&(i < (y_start + height))&&(j >= x_start)&&(j < (x_start + width)))
			{
				b= (*(data_buff + 0))&0x000000ff;
				g= (*(data_buff + 1))&0x000000ff;
				r= (*(data_buff + 2))&0x000000ff;	
				
				data_buff = data_buff + 3;
			}
			else
			{
				r = 0;
				g = 0;
				b = 0;
			}

			word = ((r<<0)|(g<<8) |(b<<16));
			
			//buf.vaddr[(i)*buf.width+(j)] = word;

			rkdrm_show_argb(j,i,1,1,a,b,g,r);

		}
	}

	end_time = platform_get_microsecond();

	log_i("time =%d\n",end_time - start_time);
	//*****************************************************
}


int show_jpeg_edp(const char *data_buff,int w ,int h)
{

	int width   = w;
	int height  = h;

	int x_start = 0;
	int y_start = 0;

	long start_time = 0;
	long end_time	= 0;
	
	//*****************************************************

	if(!data_buff)
		return 0;
	//*****************************************************
	if(width > EDP_LCD_WIDTH)
	{
		width = EDP_LCD_WIDTH;
	}
	
	if(height > EDP_LCD_HEIGHT)
	{
		height = EDP_LCD_HEIGHT;
	}

	x_start = (EDP_LCD_WIDTH  - width)/2;
	y_start = (EDP_LCD_HEIGHT - height)/2;
	//*****************************************************

#if 0
	log_i("x_start=%d\n",x_start);
	log_i("y_start=%d\n",y_start);

	log_i("width =%d\n",width);
	log_i("height=%d\n",height);
#endif
	//*****************************************************

	start_time = platform_get_microsecond();

	//*****************************************************

	rkdrm_show_buff_edp(x_start,y_start,width,height,data_buff);
	//*****************************************************

	end_time = platform_get_microsecond();
	//*****************************************************

	//log_i("time =%d\n",end_time - start_time);
	//*****************************************************
}

int show_jpeg_hdmi(const char *data_buff,int w ,int h)
{

	int width   = w;
	int height  = h;

	int x_start = 0;
	int y_start = 0;

	long start_time = 0;
	long end_time	= 0;
	
	//*****************************************************

	if(!data_buff)
		return 0;
	//*****************************************************
	if(width > HDMI_LCD_WIDTH)
	{
		width = HDMI_LCD_WIDTH;
	}
	
	if(height > HDMI_LCD_HEIGHT)
	{
		height = HDMI_LCD_HEIGHT;
	}	

	x_start = (HDMI_LCD_WIDTH  - width)/2;
	y_start = (HDMI_LCD_HEIGHT - height)/2;
	//*****************************************************

#if 0
	log_i("x_start=%d\n",x_start);
	log_i("y_start=%d\n",y_start);

	log_i("width =%d\n",width);
	log_i("height=%d\n",height);
#endif
	//*****************************************************

	start_time = platform_get_microsecond();

	//*****************************************************
	//rkdrm_show_buff_hdmi2(data_buff,width*height*3);
	rkdrm_show_buff_hdmi(x_start,y_start,width,height,data_buff);
	//*****************************************************

	end_time = platform_get_microsecond();
	//*****************************************************

	//log_i("time =%d\n",end_time - start_time);
	//*****************************************************
}

int decode_and_show_jpeg(char *filename,int lcd_index)
{

	int ret;

	int i = 0;
	int j = 0;
	
	int dst_w = 0;
	int dst_h = 0;

	int src_w = 0;
	int src_h = 0;

	int bpp   = 0;
		
	struct jpeg_file jf;

	//**************************************************

	jf.fp= fopen(filename, "rb");
	if (jf.fp== NULL) {
		log_e("can not open file,%s\n",filename);
		return -1;
	}
	
	memset(jf.filename,0,sizeof(jf.filename));
	memcpy(jf.filename,filename,strlen(filename));

	ret =is_jpeg_file(filename,&jf);
	if(ret < 0 ){
		log_e("not jpeg file");
		
    	fclose(jf.fp);
		return -1;
	}

	ret = decode_jpeg(filename,&jf);
	if(ret < 0 ){
		log_e("decode jpeg wrong\n");
		fclose(jf.fp);
		return -1;
	}
	//***********************************************************************************************
	src_w  = CODEC_ALIGN(jf.width, 4);
    src_h  = CODEC_ALIGN(jf.height, 4);
	//***********************************************************************************************


	for(i = 0;i < jf.height;i++)
	{
		memcpy(image_src_buff + i*src_w*jf.Bpp,jf.buffer + i*jf.width*jf.Bpp ,jf.width*jf.Bpp);	
	}
	//***********************************************************************************************

	if((jf.width >= LCD_WIDTH)&&(jf.height >= LCD_HEIGHT))
	{
		dst_w = LCD_WIDTH;
		dst_h = LCD_HEIGHT;
	}
	else if((jf.width >= LCD_WIDTH)&&(jf.height < LCD_HEIGHT))
	{	
		dst_w = (jf.width*LCD_HEIGHT/jf.height);
		dst_h = LCD_HEIGHT;
	}
	else if((jf.width < LCD_WIDTH)&&(jf.height >= LCD_HEIGHT))
	{
		dst_w = (jf.width*LCD_HEIGHT)/jf.height;
		dst_h = LCD_HEIGHT;
	}
	else 
	{
		dst_w = jf.width;
		dst_h = jf.height;
	}
	//***********************************************************************************************

	dst_w  = CODEC_ALIGN(dst_w, 4);
    dst_h  = CODEC_ALIGN(dst_h, 4);
	//***********************************************************************************************

	ret = rga_rgbdata_resize(image_src_buff,src_w,src_h,jf.Bpp,
							 image_dst_buff,dst_w,dst_h,jf.Bpp);
	//***********************************************************************************************
	if(ret >= 0)
	{
		if(lcd_index == 0)
		{
			show_jpeg_edp(image_dst_buff,dst_w,dst_h);
		}

		if(lcd_index == 1)
		{
			show_jpeg_hdmi(image_dst_buff,dst_w,dst_h);
		}	
	}
	else
	{
		log_i("jf.width =%d\n",jf.width);
		log_i("jf.height=%d\n",jf.height);	
				
		log_i("src_w =%d\n",src_w);
		log_i("src_h =%d\n",src_h);	

		log_i("dst_w =%d\n",dst_w);
		log_i("dst_h =%d\n",dst_h);	
	}
	//***********************************************************************************************					

	
	//***********************************************************************************************
	
	fclose(jf.fp);
	free_jpeg(&jf);
	
	//***********************************************************************************************
	
	return ret;

}



int decode_edp_show_jpeg(char *filename)
{

	int ret;

	int i = 0;
	int j = 0;
	
	int dst_w = 0;
	int dst_h = 0;

	int src_w = 0;
	int src_h = 0;

	int bpp   = 0;
		
	struct jpeg_file jf;

	//**************************************************

	jf.fp= fopen(filename, "rb");
	if (jf.fp== NULL) {
		log_e("can not open file,%s\n",filename);
		return -1;
	}
	
	memset(jf.filename,0,sizeof(jf.filename));
	memcpy(jf.filename,filename,strlen(filename));

	ret =is_jpeg_file(filename,&jf);
	if(ret < 0 ){
		log_e("not jpeg file");
		
    	fclose(jf.fp);
		return -1;
	}

	ret = decode_jpeg(filename,&jf);
	if(ret < 0 ){
		log_e("decode jpeg wrong\n");
		fclose(jf.fp);
		return -1;
	}
	//***********************************************************************************************
	src_w  = CODEC_ALIGN(jf.width, 4);
    src_h  = CODEC_ALIGN(jf.height, 4);
	//***********************************************************************************************

	for(i = 0;i < jf.height;i++)
	{
		memcpy(image_src_buff + i*src_w*jf.Bpp,jf.buffer + i*jf.width*jf.Bpp ,jf.width*jf.Bpp);	
	}
	//***********************************************************************************************

	if((jf.width >= EDP_LCD_WIDTH)&&(jf.height >= EDP_LCD_HEIGHT))
	{
		dst_w = EDP_LCD_WIDTH;
		dst_h = EDP_LCD_HEIGHT;
	}
	else if((jf.width >= EDP_LCD_WIDTH)&&(jf.height < EDP_LCD_HEIGHT))
	{	
		dst_w = (jf.width*EDP_LCD_HEIGHT/jf.height);
		dst_h = EDP_LCD_HEIGHT;
	}
	else if((jf.width < EDP_LCD_WIDTH)&&(jf.height >= EDP_LCD_HEIGHT))
	{
		dst_w = (jf.width*EDP_LCD_HEIGHT)/jf.height;
		dst_h = EDP_LCD_HEIGHT;
	}
	else 
	{
		dst_w = jf.width;
		dst_h = jf.height;
	}
	//***********************************************************************************************

	dst_w  = CODEC_ALIGN(dst_w, 4);
    dst_h  = CODEC_ALIGN(dst_h, 4);
	//***********************************************************************************************

	ret = rga_rgbdata_resize(image_src_buff,src_w,src_h,jf.Bpp,
							 image_dst_buff,dst_w,dst_h,jf.Bpp);
	
	//***********************************************************************************************
	if(ret >= 0)
	{
		show_jpeg_edp(image_dst_buff,dst_w,dst_h);
	}
	else
	{
		log_i("jf.width =%d\n",jf.width);
		log_i("jf.height=%d\n",jf.height);	
				
		log_i("src_w =%d\n",src_w);
		log_i("src_h =%d\n",src_h);	

		log_i("dst_w =%d\n",dst_w);
		log_i("dst_h =%d\n",dst_h);	
	}
	//***********************************************************************************************					

	
	//***********************************************************************************************
	
	fclose(jf.fp);
	free_jpeg(&jf);
	
	//***********************************************************************************************
	
	return ret;

}


int decode_hdmi_show_jpeg(char *filename)
{

	int ret;

	int i = 0;
	int j = 0;
	
	int dst_w = 0;
	int dst_h = 0;

	int src_w = 0;
	int src_h = 0;

	int bpp   = 0;
		
	struct jpeg_file jf;

	//**************************************************

	jf.fp= fopen(filename, "rb");
	if (jf.fp== NULL) {
		log_e("can not open file,%s\n",filename);
		return -1;
	}
	
	memset(jf.filename,0,sizeof(jf.filename));
	memcpy(jf.filename,filename,strlen(filename));

	ret =is_jpeg_file(filename,&jf);
	if(ret < 0 ){
		log_e("not jpeg file");
		
    	fclose(jf.fp);
		return -1;
	}

	ret = decode_jpeg(filename,&jf);
	if(ret < 0 ){
		log_e("decode jpeg wrong\n");
		fclose(jf.fp);
		return -1;
	}
	//***********************************************************************************************
	src_w  = CODEC_ALIGN(jf.width, 4);
    src_h  = CODEC_ALIGN(jf.height, 4);
	//***********************************************************************************************


	for(i = 0;i < jf.height;i++)
	{
		memcpy(image_src_buff + i*src_w*jf.Bpp,jf.buffer + i*jf.width*jf.Bpp ,jf.width*jf.Bpp);	
	}
	//***********************************************************************************************
#if 0
	if((jf.width >= HDMI_LCD_WIDTH)&&(jf.height >= HDMI_LCD_HEIGHT))
	{
		dst_w = HDMI_LCD_WIDTH;
		dst_h = HDMI_LCD_HEIGHT;
	}
	else if((jf.width >= HDMI_LCD_WIDTH)&&(jf.height < HDMI_LCD_HEIGHT))
	{	
		dst_w = (jf.width*HDMI_LCD_HEIGHT/jf.height);
		dst_h = HDMI_LCD_HEIGHT;
	}
	else if((jf.width < HDMI_LCD_WIDTH)&&(jf.height >= HDMI_LCD_HEIGHT))
	{
		dst_w = (jf.width*HDMI_LCD_HEIGHT)/jf.height;
		dst_h = HDMI_LCD_HEIGHT;
	}
	else 
	{
		dst_w = jf.width;
		dst_h = jf.height;
	}
#elif 0

	dst_w = HDMI_LCD_HEIGHT;
	dst_h = (jf.width*HDMI_LCD_WIDTH)/jf.height;
#elif 1

	dst_w = HDMI_LCD_HEIGHT;
	dst_h = HDMI_LCD_WIDTH;

#endif
	//***********************************************************************************************

	dst_w  = CODEC_ALIGN(dst_w, 4);
    dst_h  = CODEC_ALIGN(dst_h, 4);
	//***********************************************************************************************

	ret = rga_rgbdata_resize(image_src_buff,src_w,src_h,jf.Bpp,
							 image_dst_buff,dst_w,dst_h,jf.Bpp+1);


	//ret = rga_rgbdata_rotation(image_dst_buff,image_dst_rotate_buff,dst_w,dst_h);						 
	//***********************************************************************************************
	if(ret >= 0)
	{
		show_jpeg_hdmi(image_dst_buff,dst_w,dst_h);
	}
	else
	{
		log_i("jf.width =%d\n",jf.width);
		log_i("jf.height=%d\n",jf.height);	
				
		log_i("src_w =%d\n",src_w);
		log_i("src_h =%d\n",src_h);	

		log_i("dst_w =%d\n",dst_w);
		log_i("dst_h =%d\n",dst_h);	
	}
	//***********************************************************************************************					

	
	//***********************************************************************************************
	
	fclose(jf.fp);
	free_jpeg(&jf);
	
	//***********************************************************************************************
	
	return ret;

}


int lib_jpeg_init(void)
{
	log_i("lib jpeg init.\n");

	image_src_buff = malloc(MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);
	if(image_src_buff >= 4*1024*1024*1024)
	{
		log_e("src buff more than 4G,0x%x\n",image_src_buff);
	}


	image_dst_buff = malloc(MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);
	if(image_dst_buff >= 4*1024*1024*1024)
	{
		log_e("dst buff more than 4G,0x%x\n",image_dst_buff);
	}

	image_dst_rotate_buff = malloc(MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);
	if(image_dst_rotate_buff >= 4*1024*1024*1024)
	{
		log_e("dst buff more than 4G,0x%x\n",image_dst_buff);
	}
	


	return 0;
}


int lib_jpeg_deinit(void)
{
	log_i("lib jpeg exit.\n");






	return 0;
}
